package com.wenhuitec.android.tang.ui.activity;

import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.iot.bpaas.api.BPaaSApi;
import com.alipay.iot.bpaas.api.service.BPaaSCallback;
import com.alipay.iot.bpaas.api.service.BPaaSResponse;
import com.alipay.iot.bpaas.api.service.LocalService;
import com.alipay.iot.sdk.APIManager;
import com.alipay.iot.sdk.payment.PaymentAPI;
import com.alipay.iot.sdk.utils.SystemUtils;
import com.alipay.zoloz.smile2pay.verify.Smile2PayResponse;
import com.dhkj.web.utils.MyObserverRes;
import com.dhkj.web.utils.RequestUtils;
import com.wenhuitec.android.tang.R;
import com.wenhuitec.android.tang.ali.AliRead;
import com.wenhuitec.android.tang.config.SystemInit;
import com.wenhuitec.android.tang.entity.DeviceCarModel;
import com.wenhuitec.android.tang.sysui.model.PayModel;
import com.wenhuitec.android.tang.util.BytesUtil;
import com.wenhuitec.android.tang.util.PrintUtil;
import com.wenhuitec.android.tang.util.UsbPrinter;
import com.yzy.voice.VoicePlay;

import org.greenrobot.eventbus.EventBus;

import java.util.List;
import java.util.Map;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import io.reactivex.rxjava3.disposables.Disposable;

import static java.lang.Thread.sleep;

public class AliFaceActivity extends AppCompatActivity {

    private final String TAG = "AliFaceActivity";
    private Context mContext;
    private String orders = "";
    private UsbPrinter usbPrinter;
    private Button cancelBut;
    Disposable mdDisposable;
    private TextView priceTv;
    private TextView msgTv;
    private String price = "";
    private String mSessionId = "";
    private String mTradeNo = "";
    private String faceToken = "";
    private AliRead aliRead = new AliRead();

    private String templateId = "2021004104615091";

    private String abcpApplicationAppId = "2021004101630874";

    private String templateServiceCode = "BPaaSTemplateChannel";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scan_qr);
        mContext = this;
        String data = this.getIntent().getExtras().getString("data");
        usbPrinter = UsbPrinter.getInstance(this);
        ImageView qrScanImg = (ImageView) findViewById(R.id.qrScanImg);
        qrScanImg.setVisibility(View.GONE);
        ImageView faceScanImg = (ImageView) findViewById(R.id.faceScanImg);
        faceScanImg.setVisibility(View.VISIBLE);
        cancelBut = findViewById(R.id.cancel_button);
        priceTv = findViewById(R.id.priceTv);
        msgTv = findViewById(R.id.msgTv);
        msgTv.setText("请刷脸支付");
        List<DeviceCarModel> deviceCarModelList = JSONArray.parseArray(data, DeviceCarModel.class);
        if (deviceCarModelList == null ||
                deviceCarModelList.isEmpty() ||
                deviceCarModelList.get(0).getCarFoods().isEmpty()) {
            finish();
            return;
        }
        RequestUtils.preFacePay(mContext, new MyObserverRes<Map<String, String>>(mContext) {
            @Override
            public void onSuccess(Map<String, String> result) {
                System.out.println(result.toString());
                orders = result.get("orders");
                price = result.get("amountPrice");
                priceTv.setText(String.format("￥%s", result.get("amountPrice")));
            }

            @Override
            public void onFailure(Throwable e, String errorMsg) {
                System.out.println(errorMsg);
            }
        }, data);
        VoicePlay.with(mContext).showQR();  //播报请出示二维码
        cancelBut.setOnClickListener(v -> finish());

        Button checkBut = findViewById(R.id.check_button);
        checkBut.setOnClickListener(view -> showInputPassword());

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("tradeAmount", price);

        Bundle bundle = new Bundle();
        bundle.putString("templateId", templateId);
        bundle.putString("operateType", "startVerify");
        bundle.putString("page", "faceVerify");
        bundle.putString("templateParams", jsonObject.toJSONString());

        BPaaSApi.getInstance().startBPaaSService(abcpApplicationAppId,
                templateServiceCode, bundle, new BPaaSCallback() {
                    @Override
                    public void onResponse(BPaaSResponse response) {
                        if (response == null) {
                            Log.e(TAG, "response is null");
                            return;
                        }
                        if (response.getCode() == BPaaSResponse.RESULT_CODE_FAIL) {
                            String subCode = response.getSubCode();
                            String subMsg = response.getSubMsg();
                            // bpaas服务调用失败
                            Log.e(TAG, "bpaas transfer fail subCode = " + subCode + ",subMsg = " + subMsg);
                        } else if (response.getCode() == BPaaSResponse.RESULT_CODE_SUCCESS) {
                            Log.i(TAG, "onResponse :" + response);
                            if (response.getResult() != null) {
                                Bundle result = response.getResult().getBundle(LocalService.KEY_LOCAL_RESULT);
                                if (result != null) {
                                    int code = result.getInt("code");
                                    Log.i(TAG, "code:" + code);
                                    Bundle extInfo = result.getBundle("extInfo");
                                    if (extInfo != null) {
                                        String resultStr = extInfo.getString("result");
                                        if (!TextUtils.isEmpty(resultStr)) {
                                            JSONObject extJson = JSONObject.parseObject(resultStr);
                                            int resultCode = extJson.getIntValue("code");
                                            if (resultCode == Smile2PayResponse.CODE_SUCCESS) {
                                                //刷脸成功
                                                mSessionId = extJson.getString("sessionId");
                                                mTradeNo = extJson.getString("tradeNo");
                                                faceToken = extJson.getString("ftoken");
                                                String alipayUid = extJson.getString("alipayUid");
                                                System.out.println("接收：" + faceToken + "\nUUID" + alipayUid);

                                                PaymentAPI api = APIManager.getInstance().getPaymentAPI();
                                                String terminal_params = api.signWithDelegated(faceToken);

                                                System.out.println("terminal_paramss:" + terminal_params);

                                                String userId = getSharedPreferences("systemI", Context.MODE_PRIVATE).getString("user", "");
                                                PayModel payModel = new PayModel();
                                                payModel.setPayWay(2);
                                                payModel.setDeviceId(SystemUtils.getSerialNumber());
                                                payModel.setFaceToken(faceToken);
                                                payModel.setAliUid(alipayUid);
                                                payModel.setUserId(userId);
                                                payModel.setOrders(orders);
                                                payModel.setTerminal_params(terminal_params);
                                                RequestUtils.facePay(mContext, JSONObject.toJSONString(payModel), new MyObserverRes<String>(mContext) {
                                                    @Override
                                                    public void onSuccess(String result) {
                                                        if (mdDisposable != null && !mdDisposable.isDisposed()) {
                                                            mdDisposable.dispose();
                                                            mdDisposable = null;
                                                        }
                                                        msgTv.setText("支付成功");
                                                        List<DeviceCarModel> deviceCarModels = JSONArray.parseArray(result, DeviceCarModel.class);
                                                        try {
                                                            for (DeviceCarModel goo : deviceCarModels) {
                                                                PrintUtil.setPrintDevice(SystemInit.getInstance(mContext).getPrintDeviceType());
                                                                byte[] printByte = BytesUtil.printOrder(goo);
                                                                if (printByte != null) {
                                                                    usbPrinter.write(printByte);
                                                                }
                                                            }
                                                        } catch (Exception e) {
                                                            e.printStackTrace();
                                                        }
                                                        JSONObject params = new JSONObject();
                                                        params.put("msg", "支付成功");
                                                        params.put("amount", price);
                                                        goFacePayResultSuccess(params, faceToken);
                                                    }

                                                    @Override
                                                    public void onFailure(Throwable e, String errorMsg) {
                                                        msgTv.setText(errorMsg);
                                                    }
                                                });
                                            } else {
                                                // 刷脸失败处理
                                                String subCode = extJson.getString("subCode");
                                                String subMessage = extJson.getString("subMessage");
                                                Log.e(TAG, "startVerify fail result : code = " + resultCode + ",subCode = " + subCode + ",subMessage = " + subMessage);
                                                if ("Z6003".equals(subCode) || "Z6002".equals(subCode)) {
                                                    finish();
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        } else {
                            Log.w(TAG, "response.getCode:" + response.getCode());
                        }
                    }

                    @Override
                    public void onEvent(String eventId, String data, Bundle extra) {
                        Log.i(TAG, "onEvent eventId:" + eventId + ",data:" + data);
                        JSONObject response = JSON.parseObject(data);
                        String eventType = response.getString("messageType");
                        JSONObject content = JSON.parseObject(response.getString("messageContent"));
                        Log.i("onEvent, content: ", content.toString());
                        if (eventType.equals("SMILE_NEW_SESSION")) { // 每次刷脸都会将当次的sessionId和tradeNo通过onEvent回调过来
                            mSessionId = content.getString("sessionId");
                            mTradeNo = content.getString("tradeNo");
                            Log.d(TAG, "sessionId== " + mSessionId + ".." + "tradeNo==" + mTradeNo);
                        }
                    }
                });
    }

    public void goFacePayResultSuccess(JSONObject reqJson, String faceToken) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("sessionId", mSessionId);
        jsonObject.put("ftoken", faceToken);
        jsonObject.put("tradeNo", mTradeNo);
        jsonObject.put("success", true); // 必填，false为支付失败
        jsonObject.put("resultTimeOut", 5); //倒计时
        JSONObject outerSummary = new JSONObject();
        outerSummary.put("enablePaymentVoice", true);
        outerSummary.put("actualAmount", reqJson.getString("amount"));
        outerSummary.put("title", reqJson.getString("msg"));
        JSONObject advancedConfig = new JSONObject();
        advancedConfig.put("version", "2.0");
        advancedConfig.put("OuterSummary", outerSummary);
        //advancedConfig.put("OuterExtends", reqJson.getJSONArray("outerExtends"));
        jsonObject.put("advancedConfig", advancedConfig.toJSONString());
        Bundle bundle = new Bundle();
        bundle.putString("templateId", templateId);
        bundle.putString("operateType", "showScanFaceOfflinePayResult");// 刷卡/扫码都使用这个operateType
        bundle.putString("page", "payResult");
        bundle.putString("templateParams", jsonObject.toJSONString());
        BPaaSApi.getInstance().startBPaaSService(abcpApplicationAppId,
                templateServiceCode, bundle, new BPaaSCallback() {
                    @Override
                    public void onResponse(BPaaSResponse response) {
                        AliRead aliRead = new AliRead();
                        aliRead.responseInvoke(response, "showScanCardOfflinePayResult");
                        EventBus.getDefault().post(new Object());
                    }

                    @Override
                    public void onEvent(String eventId, String data, Bundle extra) {
                        Log.i(TAG, "onEvent eventId:" + eventId + ",data:" + data);
                        JSONObject response = JSON.parseObject(data);
                        if (response != null) {
                            String eventType = response.getString("messageType");
                            switch (eventType) {
                                case "CLOSE":
                                    //支付结果页已关闭
                                    Log.i(TAG, "刷卡支付结果页已关闭");
                                    break;
                                case "ShowSuccess":
                                    //支付结果页展示成功
                                    Log.i(TAG, "刷卡支付结果页展示成功");
                                    EventBus.getDefault().post(new Object());
                                    break;
                                case "ShowFail":
                                    //支付结果页展示失败
                                    Log.i(TAG, "刷卡支付结果页展示失败");
                                    break;
                            }

                        }
                    }
                });
    }

    private void showInputPassword() {
        //播报语音
        msgTv.setText("正在查单，请检查是否要输入密码");
        //查询订单状态，直到成功或者失败
        RequestUtils.checkAliOrderStatus(mContext, orders, new MyObserverRes<String>(mContext, false) {
            @Override
            public void onSuccess(String result) {
                List<DeviceCarModel> deviceCarModels = JSONArray.parseArray(result, DeviceCarModel.class);
                if (deviceCarModels == null ||
                        deviceCarModels.isEmpty() ||
                        deviceCarModels.get(0).getResultCode() == 0) {
                    try {
                        sleep(2000);
                        showInputPassword();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return;
                }
                if (deviceCarModels.get(0).getResultCode() < 0) {
                    cancelBut.setEnabled(true);
                    msgTv.setText("支付未成功，请返回重新下单");
                    return;
                }
                msgTv.setText("支付成功");
                try {
                    for (DeviceCarModel goo : deviceCarModels) {
                        PrintUtil.setPrintDevice(SystemInit.getInstance(mContext).getPrintDeviceType());
                        byte[] printByte = BytesUtil.printOrder(goo);
                        if (printByte != null) {
                            usbPrinter.write(printByte);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                finish();
            }

            @Override
            public void onFailure(Throwable e, String errorMsg) {
                cancelBut.setEnabled(true);
                msgTv.setText(errorMsg);
            }
        });

    }
}
